#ifndef EDGEIRERATORS_H
#define EDGEIRERATORS_H

#include "ConstraintIterator.h"
#include "Relation.h"
#include "Graph.h"
#include <boost/graph/graph_traits.hpp>
#include <string>

namespace SemanticModel
{
	class Model;

	template <typename TEdgePointer>
	class RelationIterator : public ConstraintIterator<TEdgePointer>
	{
	private:
		RelationType _type;
		const VertexMap* _vertexes;
	public:
		RelationIterator(const Model& g, TEdgePointer p,
			TEdgePointer pEnd, const VertexMap& vertexes, RelationType type)
			: ConstraintIterator<TEdgePointer>(g, p, pEnd), _vertexes(&vertexes)
		{
			_type = type;
		}
		
		const wchar_t* roleA() const
		{
			const ConstraintIterator<TEdgePointer>* b = this;
			boost::graph_traits<Graph>::vertex_descriptor v = boost::source(*b->_p, *b->_g);
			const std::wstring& roleA = _vertexes->at(v);
			return roleA.data();
		}
		const Relation relation() const
		{
			return getRelation();
		}

		const wchar_t* roleB() const
		{
			const ConstraintIterator<TEdgePointer>* b = this;
			const std::wstring& roleB = _vertexes->at(boost::target(*b->_p, *b->_g));
			return roleB.data();
		}

	protected:
		virtual Relation getRelation() const
		{
			const ConstraintIterator<TEdgePointer>* b = this;
			Relation result = (*b->_g)[*b->_p];
			return result;
		}

		virtual const bool test()
		{
			RelationType type = getRelation().type();
			return type == _type || _type == NoneRelation;
		}
	};
}

#endif // EDGEIRERATORS_H
